package com.thinkgem.jeesite.modules.spider.common;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import com.thinkgem.jeesite.modules.spider.entity.SpiderConfig;
import com.thinkgem.jeesite.modules.spider.entity.SpiderLog;
import com.thinkgem.jeesite.modules.spider.service.SpiderConfigService;
import com.thinkgem.jeesite.modules.spider.service.SpiderLogService;

import us.codecraft.webmagic.Spider;

public class SpiderHandler {
	private Logger logger = LoggerFactory.getLogger(getClass());
	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	private Spider spider;
	private SpiderLogService logService;
	private SpiderConfigService configService;
	private SpiderConfig spiderConfig;
	private int retryTimes;
	private boolean isSpiderError;
	private SpiderStatusBean bean;

	public SpiderHandler(Spider spider, SpiderLogService logService, SpiderConfigService configService,
			String spiderName) {
		super();
		this.spider = spider;
		this.logService = logService;
		this.configService = configService;

		bean = new SpiderStatusBean();
		bean.setSpiderId(spider.getClass().toString());
		bean.setSpiderName(spiderName);
		SpiderConfig entity = new SpiderConfig();
		entity.setSpiderId(spider.getClass().toString());
		spiderConfig = configService.get(entity);
		retryTimes = spiderConfig.getRetryTimes();
	}
	
	public String startJob(Model model) {
		if (spider != null && spider.getThreadAlive() == 0) {
			try {
				isSpiderError = false;
				spider.thread(spiderConfig.getThreadNumber()).start();
			} catch (Exception e) {
				//TODO 判断哪些情况是需要stop的
				isSpiderError = true;
				logService.save(new SpiderLog(this.getClass().toString(), "ERROR", e.getLocalizedMessage()));
				logger.error("spider running error==>{}", e.getLocalizedMessage());
				e.printStackTrace();

				if (retryTimes > 0) {
					try {
						// 重试次数越多，等待时间越长
						long sleepTime = spiderConfig.getRetrySleeptime() * 1000 * (spiderConfig.getRetryTimes() - retryTimes + 1);
						Thread.sleep(sleepTime);
					} catch (InterruptedException e1) {
						isSpiderError = true;
						logService.save(new SpiderLog(this.getClass().toString(), "ERROR", e.getLocalizedMessage()));
						logger.error("spider thread error==>{}", e.getLocalizedMessage());
						e.printStackTrace();
					}
					startJob(model);
					retryTimes--;
				} else {
					stopJob(model);
				}
			}
		} else {
			logger.info("Spider is running!");
		}
		logger.debug("start==" + this.getClass().toString() + sdf.format(new Date()));
		model.addAttribute("AliveThreadNum", spider.getThreadAlive());
		model.addAttribute("SpiderName", "XX Links");

		return "/spiders/common/SpiderStatus";
	}
	
	public String restartJob(Model model) {
		while (spider != null) {
			try {
				Thread.sleep(10000);
				if (spider.getThreadAlive() == 0) {
					spider.stop();
					Thread.sleep(1000);
					spider.start();
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

		}

		model.addAttribute("AliveThreadNum", spider.getThreadAlive());
		model.addAttribute("SpiderName", "XX Links");
		return "/spiders/common/SpiderStatus";
	}

	@RequestMapping("/stopJob")
	public String stopJob(Model model) {
		if (spider != null) {
			spider.stop();
			spider = null;
			logger.debug("stop==" + this.getClass().toString() + sdf.format(new Date()));

			model.addAttribute("AliveThreadNum", spider.getThreadAlive());
			model.addAttribute("SpiderName", "XX Links");
		}

		return "spiders/common/SpiderStatus";
	}

	public boolean isSpiderRunning() {
		if (spider == null) {
			return false;
		}
		return this.spider.getThreadAlive() > 0;
	}

	public int aliveThreadNum() {
		if (spider == null) {
			return -1;
		}
		return spider.getThreadAlive();
	}
}
